﻿using System;
using System.Collections.Generic;
using System.Text;

namespace chudb
{
    public class ChuQuery
    {
        internal BsonExpression Q_Count = BsonExpression.Create("COUNT(*)");
        internal BsonExpression Q_All = BsonExpression.Create("*");
        internal ChuSpace space { get; set; }
        internal Query query { get; set; }
        internal ChuQuery(ChuSpace space)
        {
            this.space = space;
            this.query = new Query();
            query.Select = Q_All;
        }
        public int Offset { get { return query.Offset; } }
        public ChuQuery Where(params BsonExpression[] expressions)
        {
            query.Where.AddRange(expressions);
            return this;
        }
        public ChuQuery SetOffset(int offset)
        {
            query.Offset = offset; return this;
        }
        public ChuQuery OrderBy(string _exp, int order)
        {
            query.OrderBy = _exp; query.Order = order;  return this;
        }
        public ChuQuery GroupBy(BsonExpression _exp)
        {
            query.GroupBy = _exp; return this;
        }
        public ChuQuery Having(BsonExpression _exp)
        {
            query.Having = _exp; return this;
        }
        public ChuQuery Limit(int limit)
        {
            query.Limit = limit; return this;
        }
        public IEnumerable<BsonDocument> ToEnumerable()
        {
            foreach (var bson in space.Engine.Query(space.SName, query).ToEnumerable()) yield return bson.AsDocument;
        }
        public BsonDocument First()
        {
            Limit(1);
            if (Count == 0) return null;
            return space.Engine.Query(space.SName, query).First().AsDocument;
        }
        public int Count {
            get
            {
                query.Select = Q_Count;
                var count = space.Engine.Query(space.SName, query).FirstOrDefault()?.AsDocument["expr"] ?? 0;
                query.Select = Q_All;
                return count;
            }
        }
        public string ToString()
        {
            return query.ToSQL(space.SName);
        }
    }
}
